<template>
  <div ref="container" class="button-container" @click="clickContainer">
    <button>
      <slot></slot>
      <span
        v-for="(r, index) in ripples"
        :key="r.key"
        :style="{
          width: `${widthHeight}px`,
          height: `${widthHeight}px`,
          left: `${r.left}px`,
          top: `${r.top}px`,
        }"
        class="ripple"
        @animationend="end(index)"
      ></span>
    </button>
  </div>
</template>

<script>
export default {
  name: 'Button',
  data() {
    return {
      containerXY: null,
      widthHeight: '',
      ripples: [],
    }
  },
  mounted() {
    this.widthHeight = this.$refs.container.offsetWidth
    this.containerXY = this.calculate(this.$refs.container)
  },
  methods: {
    calculate(ele) {
      const { top, left } = ele.getBoundingClientRect()
      return {
        x: left + window.pageXOffset,
        y: top + window.pageYOffset,
      }
    },

    clickContainer(e) {
      const obj = {
        left: e.pageX - this.containerXY.x - this.widthHeight / 2,
        top: e.pageY - this.containerXY.y - this.widthHeight / 2,
        key: Math.random() + Date.now(),
      }
      this.ripples.push(obj)
    },

    end(index) {
      this.ripples.splice(index, 1)
    },
  },
}
</script>

<style scoped>
.button-container {
  display: inline-block;
  position: relative;
  border-radius: 4px;
  overflow: hidden;
}
.button-container button {
  box-sizing: border-box;
  padding: 12px 20px;
  line-height: 1;
  background-color: #409eff;
  border: 1px solid #409eff;
  color: #fff;
  font-size: 14px;
  border-radius: 4px;
  cursor: pointer;
  user-select: none;
}
.ripple {
  display: inline-block;
  position: absolute;
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 50%;
  transform: scale(0);
  opacity: 1;
  cursor: pointer;
  animation: effect 0.3s linear;
}

@keyframes effect {
  0% {
    transform: scale(0);
    opacity: 1;
  }
  100% {
    transform: scale(2);
    opacity: 0;
  }
}
</style>
